package com.caocaog.market.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.caocaog.market.entity.MemberPointStatement;
import com.caocaog.market.mapper.MemberPointStatementMapper;
import com.caocaog.market.service.IMemberPointStatementService;
import com.caocaog.market.util.Strings;
import com.caocaog.market.vo.MemberPointModifyVO;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.constant.CacheConstant;
import org.jeecg.common.util.RedisUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;

/**
 * @Description: 客户积分流水
 * @Author: jeecg-boot
 * @Date: 2023-12-01
 * @Version: V1.0
 */
@Service
@Slf4j
public class MemberPointStatementServiceImpl extends ServiceImpl<MemberPointStatementMapper, MemberPointStatement> implements IMemberPointStatementService {

    @Resource
    private RedisUtil redisUtil;


    /**
     * 获取客户的积分信息优先走Cache
     *
     * @param memberId 客户id
     * @return 积分数据
     */
    @Override
    public List<MemberPointStatement> getMemberPointByCache(String memberId) {
        return redisUtil.executeHGetWithLock(CacheConstant.YX_CACHE_MEMBER_POINT_STATEMENT, memberId, () -> getMemberPointStatementByMemberId(memberId));
    }

    /**
     * 将客户的积分台账塞入缓存，当然也可用于更新缓存
     *
     * @param memberId 客户ID
     */
    @Override
    public void setMemberPointToCache(String memberId) {
        List<MemberPointStatement> statementList = getMemberPointStatementByMemberId(memberId);
        String key = CacheConstant.YX_CACHE_MEMBER_POINT_STATEMENT;
        redisUtil.set(Strings.buildRedisKey(key, memberId), statementList, CacheConstant.COMM_ALIVE_TIME);
    }

    /**
     * 根据客户ID查询出台账List,走DB
     *
     * @param memberId 客户ID
     * @return 查询出来的积分台账List
     */
    @Override
    public List<MemberPointStatement> getMemberPointStatementByMemberId(String memberId) {
        return list(new LambdaQueryWrapper<MemberPointStatement>().eq(MemberPointStatement::getMemberId, memberId));
    }

    /**
     * 从数据库中获取真实的客户账户积分
     *
     * @param memberId 客户id
     * @return 客户积分数量，从DB获取
     */
    @Override
    public BigDecimal getMemberPointByDB(String memberId) {
        return getMemberPointStatementByMemberId(memberId).stream().map(MemberPointStatement::getModifyPoint).reduce(BigDecimal.ZERO, BigDecimal::add);
    }


    /**
     * 修改客户的积分情况，根据传入的modifyPoint而定为正则为点数增加，为负则为点数减少
     *
     * @param memberPointModifyVO 积分变动VO类
     * @see BigDecimal#negate()
     */
    @Override
    public BigDecimal modifyMemberPoint(MemberPointModifyVO memberPointModifyVO) {
        // 先构建出一条积分变动数据
        MemberPointStatement memberPointStatement = new MemberPointStatement();
        memberPointStatement.setModifyPoint(memberPointModifyVO.getPoint()).setMemberId(memberPointModifyVO.getMemberId()).setModifyMessage(memberPointModifyVO.getModifyMessage()).setModifyType(memberPointModifyVO.getModifyType());
        // 查询数据库获得当前客户的积分信息
        BigDecimal memberPointByDB = getMemberPointByDB(memberPointModifyVO.getMemberId());
        // 原本积分信息加上传过来的变动值，得到变动后的积分信息
        BigDecimal afterAddPointCount = memberPointByDB.add(memberPointModifyVO.getPoint());
        memberPointStatement.setNowPoint(afterAddPointCount);
        save(memberPointStatement);
        // 更新缓存数据
        setMemberPointToCache(memberPointStatement.getMemberId());
        // 返回变动后的积分数量
        return afterAddPointCount;
    }

}
